import os
import sys
import threading
import time
import base64
from pathlib import Path
from flask import Flask, render_template, request, jsonify, Response
from flask_socketio import SocketIO
from dotenv import load_dotenv
import cv2
import numpy as np
from datetime import datetime
from backend.admin import admin_bp
import markdown

# Add the project root to the Python path
sys.path.append(str(Path(__file__).resolve().parent))

# Import modules
from backend.face_recognition.face_recognizer import FaceRecognizer
from backend.voice_processing.voice_assistant import VoiceAssistant
from backend.utils.logger import setup_logger
# Import LeaveManager (假设请假管理功能在 backend/leave_request 目录下)
from backend.quicklyButton.leave_application import LeaveApplicationHandler
from database.db_connection import execute_query

# Load environment variables
load_dotenv()

# Set up logger
logger = setup_logger('app')

# Initialize Flask app
app = Flask(__name__, 
            static_folder='frontend/static',
            template_folder='frontend/templates')
app.config['SECRET_KEY'] = os.getenv('SECRET_KEY', 'dev_key')

# Initialize SocketIO
socketio = SocketIO(app, cors_allowed_origins="*")

# Global variables
face_recognizer = FaceRecognizer()
voice_assistant = None
leave_manager = None
#
#
# def leave_request_callback(employee_id, reason, status):
#     """Callback function for leave request events."""
#     logger.info(f"Leave request event: {employee_id}, Reason: {reason}, Status: {status}")
#
#     # Emit the event to connected clients
#     socketio.emit('leave_request_event', {
#         'employee_id': employee_id,
#         'reason': reason,
#         'status': status,
#         'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
#     })

def face_recognition_callback(employee_id, name):
    """Callback function for face recognition events."""
    logger.info(f"Face recognition event: {name} (ID: {employee_id})")
    
    # Emit the event to connected clients
    socketio.emit('face_recognition_event', {
        'employee_id': employee_id,
        'name': name,
        'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
    })
    
    # Notify through voice assistant
    if voice_assistant:
        voice_assistant.speak(f"您好，{name}，已为您完成打卡。")

def voice_command_callback(text):
    """Callback function for voice command events."""
    logger.info(f"Voice command received: {text}")
    
    # Emit the event to connected clients
    socketio.emit('voice_command_event', {
        'text': text,
        'timestamp': time.strftime('%Y-%m-%d %H:%M:%S')
    })

# 注册管理员蓝图
app.register_blueprint(admin_bp)

# 管理员页面路由
@app.route('/admin')
def admin_page():
    return render_template('admin.html')

# 主页路由
@app.route('/')
def index():
    return render_template('index.html')

@app.route('/api/speak', methods=['POST'])
def speak():
    """API endpoint for text-to-speech."""
    try:
        data = request.json
        text = data.get('text')
        
        if not text:
            return jsonify({'success': False, 'message': 'Text is required'}), 400
        
        # Speak the text
        voice_assistant.speak(text)
        
        return jsonify({'success': True, 'message': 'Speaking text'}), 200
    
    except Exception as e:
        logger.error(f"Error speaking text: {e}")
        return jsonify({'success': False, 'message': str(e)}), 500


@app.route('/leave_request', methods=['GET', 'POST'])
def leave_request():
    if request.method == 'GET':
        return render_template('leave_application.html')
    else:  # POST request
        try:
            data = request.get_json()
            employee_id = data.get('employee_id')
            leave_type = data.get('leave_type')
            start_date = data.get('start_date')
            end_date = data.get('end_date')
            reason = data.get('reason', '')

            result = LeaveApplicationHandler.process_leave_request(
                employee_id, leave_type, start_date, end_date, reason)
            return jsonify(result)
        except Exception as e:
            logger.error(f"Error processing leave request: {e}")
            return jsonify({'success': False, 'message': f"Server error: {str(e)}"}), 500

@app.route('/register_face', methods=['GET', 'POST'])
def register_face_page():
    if request.method == 'POST':
        try:
            # 获取表单数据
            employee_id = request.form.get('employee_id')
            name = request.form.get('name')
            department = request.form.get('department')
            position = request.form.get('position')
            
            # 获取Base64编码的图像数据
            image_data = request.form.get('image')
            if not image_data:
                return jsonify({
                    'success': False,
                    'message': '未接收到图像数据'
                })

            # 解码Base64图像数据
            try:
                # 移除Base64前缀（如果存在）
                if 'base64,' in image_data:
                    image_data = image_data.split('base64,')[1]
                
                # 解码Base64数据
                image_bytes = base64.b64decode(image_data)
                
                # 转换为numpy数组
                nparr = np.frombuffer(image_bytes, np.uint8)
                image = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
                
                if image is None:
                    return jsonify({
                        'success': False,
                        'message': '图像数据解码失败'
                    })
                
                # 将图像编码为JPEG格式的字节数据
                _, img_encoded = cv2.imencode('.jpg', image)
                image_data = img_encoded.tobytes()
                
            except Exception as e:
                app.logger.error(f"图像数据处理失败: {e}")
                return jsonify({
                    'success': False,
                    'message': '图像数据处理失败'
                })
            
            if not all([employee_id, name, department, position, image_data]):
                return jsonify({
                    'success': False,
                    'message': '请填写所有必要信息并上传人脸图像'
                })

            # 调用人脸注册方法
            success , message = face_recognizer.register_face(
                employee_id=employee_id,
                name=name,
                department=department,
                position=position,
                image_data=image_data
            )
            

            return jsonify({
                    'success': success,
                    'message': message
                })


        except Exception as e:
            app.logger.error(f"人脸注册过程中出错: {e}")
            return jsonify({
                'success': False,
                'message': f'注册过程中出错: {str(e)}'
            })
    
    return render_template('register_face.html')

# 使用帮助路由
@app.route('/help')
def help_page():
    """显示系统使用帮助页面"""
    return render_template('help.html')

# 查询制度路由
@app.route('/policy')
def policy_page():
    """显示公司制度页面"""
    try:
        # 从数据库获取所有制度
        query = "SELECT * FROM policies ORDER BY category, title"
        policies = execute_query(query)
        
        # 按类别分组
        policy_categories = {}
        for policy in policies:
            category = policy['category']
            if category not in policy_categories:
                policy_categories[category] = []
                
            # 确保created_at是有效的datetime对象
            if 'created_at' in policy and policy['created_at']:
                if not isinstance(policy['created_at'], datetime):
                    try:
                        # 尝试转换为datetime对象
                        policy['created_at'] = datetime.fromisoformat(str(policy['created_at']).replace('Z', '+00:00'))
                    except (ValueError, TypeError):
                        # 如果转换失败，设置为None
                        policy['created_at'] = None
            else:
                policy['created_at'] = None
                
            # 确保content经过处理，将\n转换为<br>
            if 'content' in policy and policy['content']:
                # 截取制度内容的前200个字符作为预览
                policy['content_preview'] = policy['content'][:200] + '...' if len(policy['content']) > 200 else policy['content']
                # 将Markdown内容转换为HTML
                policy['content_html'] = markdown.markdown(policy['content'])
                
            policy_categories[category].append(policy)
        
        return render_template('policy.html', policy_categories=policy_categories)
    except Exception as e:
        logger.error(f"获取制度信息时出错: {e}")
        return render_template('policy.html', error=str(e))

# 查看单个制度详情
@app.route('/policy/<int:policy_id>')
def policy_detail(policy_id):
    """显示制度详情页面"""
    try:
        # 从数据库获取制度详情
        query = "SELECT * FROM policies WHERE id = %s"
        policies = execute_query(query, (policy_id,))
        
        if not policies:
            return render_template('policy_detail.html', error="未找到相关制度")
            
        policy = policies[0]
        
        # 确保created_at是有效的datetime对象
        if 'created_at' in policy and policy['created_at']:
            if not isinstance(policy['created_at'], datetime):
                try:
                    # 尝试转换为datetime对象
                    policy['created_at'] = datetime.fromisoformat(str(policy['created_at']).replace('Z', '+00:00'))
                except (ValueError, TypeError):
                    # 如果转换失败，设置为None
                    policy['created_at'] = None
        else:
            policy['created_at'] = None
            
        # 确保updated_at是有效的datetime对象
        if 'updated_at' in policy and policy['updated_at']:
            if not isinstance(policy['updated_at'], datetime):
                try:
                    # 尝试转换为datetime对象
                    policy['updated_at'] = datetime.fromisoformat(str(policy['updated_at']).replace('Z', '+00:00'))
                except (ValueError, TypeError):
                    # 如果转换失败，设置为None
                    policy['updated_at'] = None
        else:
            policy['updated_at'] = None
            
        # 将Markdown内容转换为HTML
        if 'content' in policy and policy['content']:
            policy['content'] = markdown.markdown(policy['content'])
            
        return render_template('policy_detail.html', policy=policy)
    except Exception as e:
        logger.error(f"获取制度详情时出错: {e}")
        return render_template('policy_detail.html', error=str(e))

# 请假历史API
@app.route('/api/employee/leave-history/<employee_id>')
def get_employee_leave_history(employee_id):
    """获取特定员工的请假历史记录"""
    try:
        # 首先验证员工是否存在
        employee_query = "SELECT * FROM employees WHERE employee_id = %s"
        employee_result = execute_query(employee_query, (employee_id,))
        
        if not employee_result:
            return jsonify({"error": "未找到该员工信息"}), 404
            
        # 查询该员工的请假记录
        query = """
            SELECT id, employee_id, leave_type, start_date, end_date, 
                   reason, status, admin_comment, created_at
            FROM leave_requests 
            WHERE employee_id = %s
            ORDER BY created_at DESC
        """
        results = execute_query(query, (employee_id,))
        
        return jsonify(results)
    except Exception as e:
        logger.error(f"获取请假历史时出错: {e}")
        return jsonify({"error": f"服务器错误: {str(e)}"}), 500

def start_services():
    """Start the face recognition and voice assistant services."""
    global face_recognizer, voice_assistant
    
    # Initialize database if needed
    try:
        # 首先检查数据库是否已经初始化
        from database.db_connection import execute_query
        
        # 检查policies表是否存在且有数据
        check_query = """
            SELECT COUNT(*) as count FROM information_schema.tables 
            WHERE table_schema = 'attendance_system' AND table_name = 'policies'
        """
        
        result = execute_query(check_query)
        tables_exist = result and result[0]['count'] > 0
        
        if tables_exist:
            # 检查是否有数据
            policy_query = "SELECT COUNT(*) as count FROM policies"
            try:
                policy_result = execute_query(policy_query)
                has_policies = policy_result and policy_result[0]['count'] > 0
            except Exception:
                # 如果表不存在或查询失败，说明需要初始化
                has_policies = False
                
            # 仅当表不存在或没有数据时才初始化
            if not has_policies:
                logger.info("数据库表存在但没有数据，将插入初始数据")
                from database.insert_test_data import insert_test_data
                insert_test_data()
                logger.info("测试数据插入成功")
            else:
                logger.info("数据库已存在且有数据，跳过初始化")
        else:
            # 表不存在，需要完全初始化
            logger.info("数据库表不存在，将进行初始化")
            from database.init_db import init_database
            init_database(drop_existing=False)  # 不删除现有表格，只创建不存在的表
            logger.info("数据库初始化成功")
            
            # 插入测试数据
            from database.insert_test_data import insert_test_data
            insert_test_data()
            logger.info("测试数据插入成功")
            
    except Exception as e:
        logger.error(f"数据库初始化检查出错: {e}")
    
    try:
        logger.info("正在启动服务...")
        
        # 初始化并启动人脸识别
        logger.info("正在初始化人脸识别系统...")
        #face_recognizer = FaceRecognizer()
        face_recognizer.start(recognition_callback=face_recognition_callback)
        logger.info("人脸识别系统启动成功")
        
        # 初始化并启动语音助手
        logger.info("正在初始化语音助手...")
        try:
            voice_assistant = VoiceAssistant()
            voice_assistant.start(command_callback=voice_command_callback)
            logger.info("语音助手启动成功")
            
            # 播放欢迎消息
            voice_assistant.speak("智慧考勤系统已启动，欢迎使用。")
        except Exception as e:
            logger.error(f"语音助手初始化失败: {e}")
            voice_assistant = None
            logger.warning("系统将在没有语音功能的情况下继续运行")

        logger.info("所有服务启动完成")
    
    except Exception as e:
        logger.error(f"启动服务时出错: {e}")
        if face_recognizer:
            face_recognizer.stop()

def stop_services():
    """Stop the face recognition and voice assistant services."""
    global face_recognizer, voice_assistant
    
    try:
        if face_recognizer:
            face_recognizer.stop()
        
        if voice_assistant:
            voice_assistant.stop()
        
        logger.info("Face recognition and voice assistant services stopped")
    
    except Exception as e:
        logger.error(f"Error stopping services: {e}")

@socketio.on('connect')
def handle_connect():
    """Handle client connection."""
    logger.info(f"Client connected: {request.sid}")

@socketio.on('disconnect')
def handle_disconnect():
    """Handle client disconnection."""
    logger.info(f"Client disconnected: {request.sid}")

def gen_frames():
    """Generate video frames from the face recognizer's camera."""
    while True:
        if face_recognizer and face_recognizer.video_capture and face_recognizer.video_capture.isOpened():
            success, frame = face_recognizer.video_capture.read()
            if success:
                # 转换图像格式
                ret, buffer = cv2.imencode('.jpg', frame)
                if ret:
                    # 将图像转换为字节流
                    frame = buffer.tobytes()
                    yield (b'--frame\r\n'
                           b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
            else:
                break
        else:
            time.sleep(0.1)

@app.route('/video_feed')
def video_feed():
    """Video streaming route."""
    return Response(gen_frames(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

if __name__ == '__main__':
    # Start the services in a separate thread
    services_thread = threading.Thread(target=start_services)
    services_thread.daemon = True
    services_thread.start()
    
    # Register shutdown function
    import atexit
    atexit.register(stop_services)
    
    # Start the Flask app
    host = os.getenv('HOST', '0.0.0.0')
    port = int(os.getenv('PORT', 5000))
    debug = os.getenv('DEBUG', 'False').lower() == 'true'
    
    logger.info(f"Starting application on {host}:{port} (debug={debug})")
    socketio.run(app, host=host, port=port, debug=debug, allow_unsafe_werkzeug=True)

